package core;

import java.io.UnsupportedEncodingException;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.time.DateUtils;
import org.apache.log4j.Logger;
import org.apache.poi.ss.usermodel.DateUtil;

import com.dudu.utils.PhoneUtils;

import core.util.CommUtils;
import core.util.Const;
import core.util.CoreDataUtil;
import core.util.DES;

public class CoreService {

    public static final Logger log = core.util.Logger.getLogger(CoreService.class.getName());
    private HttpServletRequest request;
    private HttpServletResponse response;
    private HttpSession session;
    private CoreDao dao;

    public HttpSession getSession() {
	return session;
    }

    public void setSession(HttpSession session) {
	this.session = session;
    }

    public CoreDao getDao() {
	if (dao == null) {
	    dao = CoreDaoInvoke.getInstance();
	}
	return dao;
    }

    public void setDao(CoreDao dao) {
	this.dao = dao;
    }

    public CoreService() {
    }

    protected HttpServletRequest getRequest() {
	return request;
    }

    public void setRequest(HttpServletRequest request) {
	this.request = request;
    }

    protected HttpServletResponse getResponse() {
	return response;
    }

    public void setResponse(HttpServletResponse response) {
	this.response = response;
    }

    /**
     * 获取请求IP
     * 
     * @return
     */
    protected String getRemoteAddr() {
	String remoteAddr = "";
	String ipFromNginx = this.getRequest().getHeader("X-Real-IP"); // nginx代理时获取IP方式
	if (StringUtils.isBlank(ipFromNginx) || "unknown".equalsIgnoreCase(ipFromNginx)) {
	    remoteAddr = this.getRequest().getRemoteAddr();
	} else {
	    remoteAddr = ipFromNginx;
	}

	return remoteAddr;
    }

    /**
     * 跳转
     * 
     * @param url
     * @return
     */
    protected String toForword(Class<?> clazz, String key) {
	JSONObject obj = new JSONObject();
	obj.put(Const.STATE, 0);
	obj.put(Const.TYPE, DES.encodeOneKey(String.valueOf(Const.FORWORD), DES.key));
	obj.put(Const.KEY, key);
	obj.put(Const.NAMESPACE, clazz.getName());
	return obj.toString();
    }

    /**
     * 重定向
     * 
     * @param url
     * @return
     */
    protected String toRedirect(Class<?> clazz, String key) {
	JSONObject obj = new JSONObject();
	obj.put(Const.STATE, 0);
	obj.put(Const.TYPE, DES.encodeOneKey(String.valueOf(Const.REDIRECT), DES.key));
	obj.put(Const.KEY, key);
	obj.put(Const.NAMESPACE, clazz.getName());
	return obj.toString();
    }

    /**
     * 采用ajax方式把Map转换成功json结果集
     * 
     * @param status
     * @param data
     * @param errMsg
     * @return
     */
    protected String returnMap2Json(int status, List<Map<String, Object>> data, String errMsg) {
	JSONObject obj = new JSONObject();
	JSONObject resultObj = new JSONObject();
	obj.put(Const.STATE, String.valueOf(status));
	JSONArray array = new JSONArray();
	if (data != null && data.size() > 0) {
	    for (int i = 0; i < data.size(); i++) {
		Map<String, Object> map = data.get(i);
		JSONObject mapObj = map2Json(map);
		array.add(mapObj);
	    }
	}
	resultObj.put(Const.TYPE, DES.encodeOneKey(String.valueOf(Const.AJAX), DES.key));
	obj.put(Const.DATA, array);
	obj.put(Const.ERRMSG, errMsg);
	resultObj.put(Const.DATA, obj);
	return resultObj.toString();
    }

    /**
     * 采用ajax方式把Map转换成功Xml结果集
     * 
     * @param status
     * @param data
     * @param errMsg
     * @return
     */
    protected String returnMap2Xml(int status, List<Map<String, Object>> data, String errMsg) {
	JSONObject resultObj = new JSONObject();
	StringBuffer xml = new StringBuffer();
	xml.append("<?xml version='1.0' encoding='UTF-8'?>");
	xml.append("<entitys>");
	if (data != null && data.size() > 0) {
	    for (int i = 0; i < data.size(); i++) {
		Map<String, Object> map = data.get(i);
		String entity = map2Xml(map);
		xml.append(entity);
	    }
	}
	xml.append("</entitys>");
	resultObj.put(Const.TYPE, DES.encodeOneKey(String.valueOf(Const.AJAX), DES.key));
	resultObj.put(Const.DATA, xml.toString());
	return resultObj.toString();
    }

    /**
     * 采用ajax把json转换成结果集
     * 
     * @param status
     * @param data
     * @param errMsg
     * @return
     */
    protected String list2JsonResult(int status, List<JSONObject> data, String errMsg) {
	JSONObject obj = new JSONObject();
	JSONObject resultObj = new JSONObject();
	obj.put(Const.STATE, String.valueOf(status));
	JSONArray array = new JSONArray();
	if (data != null && data.size() > 0) {
	    for (int i = 0; i < data.size(); i++) {
		JSONObject mapObj = data.get(i);
		array.add(mapObj);
	    }
	}
	resultObj.put(Const.TYPE, DES.encodeOneKey(String.valueOf(Const.AJAX), DES.key));
	obj.put(Const.DATA, array);
	obj.put(Const.ERRMSG, errMsg);
	resultObj.put(Const.DATA, obj);
	return resultObj.toString();
    }

    protected String toMapResult(int status, Map<String, Object> data) {
	JSONObject obj = new JSONObject();
	JSONObject resultObj = new JSONObject();
	obj.put(Const.STATE, String.valueOf(status));
	obj.put(Const.DATA, map2Json(data));
	resultObj.put(Const.TYPE, DES.encodeOneKey(String.valueOf(Const.AJAX), DES.key));
	resultObj.put(Const.DATA, obj);
	return resultObj.toString();
    }

    protected String obj2JsonResult(int status, JSONObject data, String errMsg) {
	JSONObject obj = new JSONObject();
	JSONObject resultObj = new JSONObject();
	obj.put(Const.STATE, String.valueOf(status));
	obj.put(Const.ERRMSG, errMsg);
	if (data != null) {
	    obj.put(Const.DATA, data.toString());
	}
	resultObj.put(Const.TYPE, DES.encodeOneKey(String.valueOf(Const.AJAX), DES.key));
	resultObj.put(Const.DATA, obj);
	return resultObj.toString();
    }

    /**
     * 采用ajax提交
     * 
     * @param data
     * @return
     */
    protected String returnData(String data) {
	JSONObject resultObj = new JSONObject();
	resultObj.put(Const.TYPE, DES.encodeOneKey(String.valueOf(Const.AJAX), DES.key));
	resultObj.put(Const.DATA, data);
	return resultObj.toString();
    }

    private JSONObject map2Json(Map<String, Object> map) {
	JSONObject obj = new JSONObject();
	if (map != null && map.size() > 0) {
	    for (Map.Entry<String, Object> kv : map.entrySet()) {
		String key = kv.getKey();
		Object value = kv.getValue();
		obj.put(key, value == null ? "" : value);
	    }
	}
	return obj;
    }

    private String map2Xml(Map<String, Object> map) {
	StringBuffer xml = new StringBuffer();
	xml.append("<entity>");
	if (map != null && map.size() > 0) {
	    for (Map.Entry<String, Object> kv : map.entrySet()) {
		String key = kv.getKey();
		Object value = kv.getValue();
		xml.append("<").append(key).append(">");
		xml.append(CommUtils.encodeSpecile(value.toString()));
		xml.append("</").append(key).append(">");
	    }
	}
	xml.append("</entity>");
	return xml.toString();
    }

    protected String getParamete1Des(String key) {
	String value = request.getParameter(key);
	return DES.decodeOneKey(value, CoreDataUtil.DES_FIRST_KEY);
    }

    protected String getParamete2Des(String key) {
	String value = request.getParameter(key);
	return DES.decode2Key(value, CoreDataUtil.DES_FIRST_KEY, CoreDataUtil.DES_SECONDE_KEY);
    }

    protected String getParamete3Des(String key) {
	String value = request.getParameter(key);
	return DES.decode3Key(value, CoreDataUtil.DES_FIRST_KEY, CoreDataUtil.DES_SECONDE_KEY, CoreDataUtil.DES_THIRD_KEY);
    }

    protected String getParameter(String key) {
	String value = request.getParameter(key);
	if (CommUtils.isNull(value)) {
	    return "";
	}
	return value;
    }

    protected String encode1DesParameter(String data) {
	return DES.encodeOneKey(data, CoreDataUtil.DES_FIRST_KEY);
    }

    protected String encode2DesParameter(String data) {
	return DES.encode2Key(data, CoreDataUtil.DES_FIRST_KEY, CoreDataUtil.DES_SECONDE_KEY);
    }

    protected String encode3DesParameter(String data) {
	return DES.encode3Key(data, CoreDataUtil.DES_FIRST_KEY, CoreDataUtil.DES_SECONDE_KEY, CoreDataUtil.DES_THIRD_KEY);
    }

    protected String getPageSql() {
	int size = Integer.valueOf(this.getRequest().getParameter("size"));
	int start = Integer.valueOf(this.getRequest().getParameter("start"));

	return " limit " + start + ", " + size;
    }

    protected Map<String, String> convertParam() {
	Map<String, String> result = new HashMap<String, String>();
	// 查询参数
	String params = null;
	try {
	    params = new String(this.getRequest().getParameter("q").getBytes("ISO8859-1"), "UTF-8");
	} catch (UnsupportedEncodingException e) {
	    e.printStackTrace();
	}
	if (params != null) {
	    String[] paramsArray = params.split(";");
	    for (String str : paramsArray) {
		if (StringUtils.isNotBlank(str)) {
		    String[] para = str.split("=");
		    System.out.println(para[0] + "====" + para[1]);
		    result.put(para[0], para[1]);
		}
	    }
	}
	return result;
    }

    protected String convertParams() {
	// 查询参数
	String params = null;
	try {
	    params = new String(this.getRequest().getParameter("q").getBytes("ISO8859-1"), "UTF-8");
	} catch (UnsupportedEncodingException e) {
	    e.printStackTrace();
	}
	StringBuffer sqlBuffer = new StringBuffer();
	if (params != null) {
	    String[] paramsArray = params.split(";");
	    for (int i = 0; i < paramsArray.length; i++) {
		String param = paramsArray[i];
		if (StringUtils.isNotBlank(param)) {
		    if (i == 0) {
			sqlBuffer.append(" ");
		    } else {
			sqlBuffer.append(" AND ");
		    }
		    sqlBuffer.append(param);
		}
	    }
	}

	return sqlBuffer.toString();
    }

    /**
     * 检测字段
     * 
     * @param key
     * @param param
     * @param length
     * @return
     */
    protected JSONObject checkParams(List<String[]> checkParamlist) {
	// String key, String param, Integer length
	if (null == checkParamlist || checkParamlist.size() == 0) {
	    return null;
	}
	JSONObject result = new JSONObject();
	for (String[] obj : checkParamlist) {
	    String key = obj[0];// 参数名
	    String param = obj[1];// 值
	    Integer length = Integer.parseInt(obj[2]);// 长度
	    String flag = obj[3];// 0 必传项，1 非必传
	    String paramtype = obj[4];// 类型
	    if (StringUtils.isBlank(param) && flag.equals("0")) {
		result.put("result", "-1");
		result.put("describe", "参数值为空:" + key + "不能为空");
		result.put("code", "0015");
		return result;
	    }
	    if (StringUtils.isNotBlank(param) && param.length() > length) {
		result.put("result", "-1");
		result.put("describe", "参数值超长:" + key + "超长，不能超过" + length);
		result.put("code", "0009");
		return result;
	    }
	    if (StringUtils.isNotBlank(param) && paramtype.equals("phone")) {
		String[] phoneStr = param.split(",");
		for (String phone : phoneStr) {
		    if (!PhoneUtils.isMobileOrPhone(phone)) {
			result.put("result", "-1");
			result.put("describe", "号码格式错误");
			result.put("code", "0004");
			return result;
		    }
		}
	    }
	    if (StringUtils.isNotBlank(param) && paramtype.equals("json")) {
		try {
		    JSONObject authDataJson = JSONObject.fromObject(param);
		} catch (Exception e) {
		    result.put("result", "-1");
		    result.put("describe", "参数类型错误:" + key + "不是标准的" + paramtype + "类型");
		    result.put("code", "0008");
		    return result;
		}
	    }
	    if (StringUtils.isNotBlank(param) && paramtype.equals("jsonArray")) {
		try {
		    JSONArray authDataJson = JSONArray.fromObject(param);
		} catch (Exception e) {
		    result.put("result", "-1");
		    result.put("describe", "参数类型错误:" + key + "不是标准的" + paramtype + "类型");
		    result.put("code", "0008");
		    return result;
		}
	    }

	    if (StringUtils.isNotBlank(param) && paramtype.equals("date")) {
		Date data = core.util.DateUtil.parseDate(param, "");
		if (data == null) {
		    result.put("result", "-1");
		    result.put("describe", "参数类型错误:" + key + "不是标准的" + paramtype + "类型");
		    result.put("code", "0008");
		    return result;
		}

	    }
	}
	return null;
    }
}
